Proba extendre esqueletonització 2
BW_prob = llistat_imatges{1};
Retallem la imatge
[imageArray_cropped, BW_prob_cropped] = retallar_BWRGBimatge_BB(imageArray, BW_prob, 5);
imshowpair(imageArray_cropped, BW_ini_regio_cropped, "montage")
% Extenent el esquelet i reduint la única línea
[~, sfMaskBurn_new, dades_imatge] = esqueletonitzacio_josep(BW_prob_cropped, imageArray_cropped, 1, true, true);
imshow(sfMaskBurn_new); dades_imatge
% Extenent esquelet sense reduïr linia
[BW_skel, sfMaskBurn_new, dades_imatge] = esqueletonitzacio_josep(BW_prob_cropped, imageArray_cropped, 1, true, false);
imshow(sfMaskBurn_new); dades_imatge
% sense extendre esquelet sense reduïr linia
[BW_skel, sfMaskBurn_new, dades_imatge] = esqueletonitzacio_josep(BW_prob_cropped, imageArray_cropped, 1, false, false);
imshow(sfMaskBurn_new); dades_imatge
Ara probarem d'extendre la punta de l'esqueletonització de forma directe amb la imatge, i no amb el punt més proper com ocórre amb cóm és definit en la funció extendre_skel() de esqueletonitzacio_josep().
Veiem la punta de la imatge
[sfMaskBurn_new_punt, xy_punta] = imcrop(imoverlay(BW_prob_cropped, BW_skel, "r")); close
imshow(sfMaskBurn_new_punt, 'InitialMagnification','fit')
Primer de tot obtenim els endpoints
endopints_BWskel = find(bwmorph(BW_skel,'endpoints'));
% Grafiquem els endpoints
[x_endpoint, y_endpoint] = ind2sub(size(BW_prob_cropped), endopints_BWskel);
imshow(imoverlay(BW_prob_cropped, BW_skel, "r" ))
% plot(y_c, x_r, 'r-', 'LineWidth', 2);
plot(y_endpoint, x_endpoint, 'b.','markersize',14)
Obtenim l'angle
matriu_nova = BW_skel(x_endpoint-cada_val:x_endpoint+cada_val, y_endpoint-cada_val:y_endpoint+cada_val)
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
[x_matnova, y_matnova] = size(matriu_nova);
matrui_nova_2 = matriu_nova;
matrui_nova_2(2:x_matnova-1,2:x_matnova-1) = 0;
matrui_nova_2_show = matrui_nova_2; matrui_nova_2_show(((x_matnova-1)/2)+1, ((y_matnova-1)/2)+1) = 1;
imshowpair_d = imshowpair(matriu_nova, matrui_nova_2_show, "montage"); imshow(imshowpair_d.CData, 'InitialMagnification','fit')
%matriu_nova_2 = BW_skel_new(x_endpoint-cada_val2:x_endpoint+cada_val2, y_endpoint-cada_val2:y_endpoint+cada_val2)
y_1 = ((y_matnova-1)/2)+1;
x_1 = ((x_matnova-1)/2)+1;
[y_2, x_2] = find(matrui_nova_2);
angle_open = abs(atand((y_2-y_1)/(x_2-x_1)))
%plot([x_1, y_1], [x_2, y_2])
imshow(matrui_nova_2_show, 'InitialMagnification','fit')
line([x_1, x_2], [y_1, y_2])
Mirem com funciona la funcio extendre_line
% function [BW_skel_pixels, line_write_points_cell] = extendre_skel(BW_skel_inicial, BW_inicial)
BW_skel_inicial = BW_skel;
BW_inicial = BW_prob_cropped;
% Donada una imatge esqueletonitzada d'una imatge binaria, s'allarguen les
% puntes d'aquesta de manera que els extrems de la imatge esqueletonitzada
% inicial arriben a les bores de la superficie de la imatge binària.
% Nota: s'han tret els elements de graficació.
% Amb l'ajuda de MATLAB Answers: https://es.mathworks.com/matlabcentral/answers/1447854-convert-line-to-pixels-in-a-image-from-coordenade
% BW_skel_inicial - imatge esqueletonitzada
% BW_inicial - imatge binaria de la imatge esqueletonitzada
% BW_skel_pixels - imatge esqueletonitzada
% Montatge_final_pixels - montatge imatge binaria i imatge esqueletonitzda
% line_write_points_cell - cell amb els dos punts en que s'allarga la imatge esqueletonitzada
punts_ini_fini_im = bwmorph(BW_skel_inicial, 'endpoints');
[row_find, col_find] = find(punts_ini_fini_im);
endpoints_inifin = [row_find col_find];
% Busquem punts perimetrals
boundaries = bwboundaries(BW_inicial);
superf_points = boundaries{1};
% visboundaries(boundaries) %|Per a visualitzar els contorns
% imshow(BW_inicial - BW_skel_inicial)
% visboundaries(boundaries)
% % Obtenir l'angle d'una linia:
% slope = (y2 - y1) ./ (x2 - x1)
% Comparison between endpoints and superficial points
x_var_1 = endpoints_inifin(1,1);
x_var_2 = superf_points(1,1);
y_var_1 = endpoints_inifin(1,2);
y_var_2 = superf_points(1,2);
dist_var = sqrt((x_var_2-x_var_1)^2+(y_var_2-y_var_1)^2);
for cada_endp_skel = 1:length(endpoints_inifin)
% canviar el 1 inicial que es la liniaaa (cada punt)
for cada_punt_sup = 1:length(superf_points)
x_var_1 = endpoints_inifin(cada_endp_skel,1);
x_var_2 = superf_points(cada_punt_sup,1);
y_var_1 = endpoints_inifin(cada_endp_skel,2);
y_var_2 = superf_points(cada_punt_sup,2);
dist_var = sqrt((x_var_2-x_var_1)^2+(y_var_2-y_var_1)^2);
xy_coord = superf_points(cada_punt_sup,:);
xy_coord_tot = [xy_coord_tot; xy_coord];
BW_skel_graph = imoverlay(BW_inicial, BW_skel_inicial, 'r');
hold on; % Prevent image from being blown away.
plot(xy_coord_tot(1,2),xy_coord_tot(1,1),'r+', 'MarkerSize', 50);
plot(xy_coord_tot(2,2),xy_coord_tot(2,1),'r+', 'MarkerSize', 50);
% Graficar linia entre els punts:
BW_skel_pixels = BW_skel_inicial;
line_write_points_cell = {};
for cada_endpoint_saps = 1:length(endpoints_inifin)
endpoint1 = endpoints_inifin(cada_endpoint_saps, :); % xy endpoint 1
suppoint1 = xy_coord_tot(cada_endpoint_saps, :);
line_write_points = [endpoint1; suppoint1];
line_write_points_cell{cada_endpoint_saps} = line_write_points;
%line(line_write_points(:, 2),line_write_points(:, 1),'Color','y','LineWidth',4)
% Fem el mateix amb la funció de generar pixels que ens ha dit l'amic
T_var=false(size(BW_inicial));
T_var(endpoint1(1), endpoint1(2))=1; %line end point 1
T_var(suppoint1(1), suppoint1(2))=1; %line end point 2
BW_skel_pixels = BW_skel_pixels|bwconvhull(T_var);
% bwconvhull el que fa es unir els pixels que hi ha en una imatge.
% D'aquesta manera, s'uneixen els dos punts (inicial i final) que hem definit.
% Llavors la línia definida es suma a la imatge esqueletotnitzada
% line_write_points <- punts de les línies
% endpoints_inifin <- punts inicial i final de la imatge esqueletonitzada
% xy_coord_tot <- punt dels punts més pròxims
% line_write_points_cell <- cell dels line_write_points
% % Exportem, llegim i eliminem la imatge temporal (no ho se fer d'una altre manera)
% exportgraphics(gca, 'temporal_skel_llarg.png');
% imatge_arxi_ciru = imread("temporal_skel_llarg.png");
% delete temporal_skel_llarg.png
Montatge_final_pixels = imoverlay(BW_inicial, BW_skel_pixels, "r");
imshow(Montatge_final_pixels)
Apliquem nova extensio
% Obtenim els punts finals de l'esqueletonització, i la superfície de la
punts_ini_fini_im = bwmorph(BW_skel_inicial, 'endpoints');
[row_find, col_find] = find(punts_ini_fini_im);
inx_endpoints = find(punts_ini_fini_im);
endpoints_inifin = [row_find col_find]; % endpoints
% Busquem punts perimetrals
[boundaries, Leing] = bwboundaries(BW_inicial); % Elapsed time is 0.010365 seconds.
superf_points = boundaries{1};
ind = sub2ind(size(BW_inicial),superf_points(:, 1), superf_points(:, 2))
43777
44384
44992
45599
46207
46815
47423
48031
48639
49247
BW_perimeter = false(size(BW_inicial))
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW_perimeter(ind) = true;
Ara anem a obtenir la regió de la imatge, per a posteriorment veure quins pixels serien els que encaixarien amb l'angle
Obtenim els valors dels endpoints, de manera que serveixi per a poder graficar la regió de la imatge, i operar en aquesta.
BW_single_dist = bwdist(~BW_inicial);
imshow(BW_single_dist, [])
% Obtenim la distancia amb la superfície.
valors_endopints = BW_single_dist(inx_endpoints)
% Això ens permetrà expandir la imatge amb suficiencia, sense haber
% d'operar amb tota la imatge.
[matriu_nova_X, matrui_nova_2_X, matrui_nova_2_show_X, matsort, punt_centr] = matriu_nova(BW_perimeter, round(double(valors_endopints(2)))+1, x_endpoint(2), y_endpoint(2));
La imatge original
Els contorns de la imatge original
Els contorns de la imatge original, amb el punt central marcat
imshow(matrui_nova_2_show_X)
Ara anem a veure, per a cada punt de la regió de la imatge, l'angle que es forma:
% Index de cada punt de la matriu
indx_regions_perimet = find(matriu_nova_X);
indx_punt_mig = sub2ind(size(matriu_nova_X), punt_centr(1), punt_centr(2));
x_mat_1 = punt_centr(1); y_mat_1 = punt_centr(2)
for cada_indx = indx_regions_perimet'
cada_indx % Cada index de la imatge on hi ha un pixel.
[y_mat_2, x_mat_2] = ind2sub(size(matriu_nova_X), cada_indx)
angle_pix = abs(atand((y_mat_1 - y_mat_2)/(x_mat_1 - x_mat_2)));
imshow(matriu_nova_X, 'InitialMagnification','fit')
line([x_mat_1, x_mat_2], [y_mat_1, y_mat_2])
title(strcat(string(round(angle_pix, 1)), "degree"))
end
cada_indx = 15
y_mat_2 = 15
x_mat_2 = 1
cada_indx = 30
y_mat_2 = 15
x_mat_2 = 2
cada_indx = 45
y_mat_2 = 15
x_mat_2 = 3
cada_indx = 60
y_mat_2 = 15
x_mat_2 = 4
cada_indx = 61
y_mat_2 = 1
x_mat_2 = 5
cada_indx = 75
y_mat_2 = 15
x_mat_2 = 5
cada_indx = 76
y_mat_2 = 1
x_mat_2 = 6
cada_indx = 89
y_mat_2 = 14
x_mat_2 = 6
cada_indx = 91
y_mat_2 = 1
x_mat_2 = 7
cada_indx = 104
y_mat_2 = 14
x_mat_2 = 7
cada_indx = 106
y_mat_2 = 1
x_mat_2 = 8
cada_indx = 119
y_mat_2 = 14
x_mat_2 = 8
cada_indx = 121
y_mat_2 = 1
x_mat_2 = 9
cada_indx = 133
y_mat_2 = 13
x_mat_2 = 9
cada_indx = 137
y_mat_2 = 2
x_mat_2 = 10
cada_indx = 148
y_mat_2 = 13
x_mat_2 = 10
cada_indx = 153
y_mat_2 = 3
x_mat_2 = 11
cada_indx = 163
y_mat_2 = 13
x_mat_2 = 11
cada_indx = 168
y_mat_2 = 3
x_mat_2 = 12
cada_indx = 177
y_mat_2 = 12
x_mat_2 = 12
cada_indx = 184
y_mat_2 = 4
x_mat_2 = 13
cada_indx = 191
y_mat_2 = 11
x_mat_2 = 13
cada_indx = 200
y_mat_2 = 5
x_mat_2 = 14
cada_indx = 201
y_mat_2 = 6
x_mat_2 = 14
cada_indx = 206
y_mat_2 = 11
x_mat_2 = 14
cada_indx = 217
y_mat_2 = 7
x_mat_2 = 15
cada_indx = 218
y_mat_2 = 8
x_mat_2 = 15
cada_indx = 219
y_mat_2 = 9
x_mat_2 = 15
cada_indx = 220
y_mat_2 = 10
x_mat_2 = 15
cada_indx = 221
y_mat_2 = 11
x_mat_2 = 15
Fins aqui tenim que podem passar al llarg de cada pixel de la regió, i obtenir els angles.
Ara el que necessitem és: determinar l'angle de la última regió de la imatge esqueletonitzada
Per a fer-ho, tornarem a agafar la regió de la imatge, però aquesta vegada serà la imatge esqueletonitzada, i agafarem l'angle últim que es forma, i en farem la mitja dels últims punts:
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, 4, x_endpoint(2), y_endpoint(2));
La imatge original
imshow(matriu_nova_skel, 'InitialMagnification','fit')
Els contorns de la imatge original
imshow(matrui_nova_2_skel, 'InitialMagnification','fit')
Els contorns de la imatge original, amb el punt central marcat
imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
Si volem obtenir l'angle:
[y_mat_skel, x_mat_skel] = find(matrui_nova_2_skel)
y_mat_skel = 4
x_mat_skel = 1
On l'angle del punt central serà:
x_mat_centr = punt_centr_skel(1); y_mat_centr = punt_centr_skel(2);
Obtenim l'angle
angle_pix = abs(atand((y_mat_centr - y_mat_skel)/(x_mat_centr - x_mat_skel)));
imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
line([x_mat_centr, x_mat_skel], [y_mat_centr, y_mat_skel])
title(strcat(string(round(angle_pix, 1)), "degree"))
Ara fem això per a cada pixel de la imatge esqueletonitzada, fins a un límit. ççç optimitzar fins a certa variació de percentatge de canvi del angle.
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, cada_n_pixel, x_endpoint(2), y_endpoint(2));
%imshow(matriu_nova_skel, 'InitialMagnification','fit')
%Els contorns de la imatge original
%imshow(matrui_nova_2_skel, 'InitialMagnification','fit')
%Els contorns de la imatge original, amb el punt central marcat
%imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
%Si volem obtenir l'angle:
[y_mat_skel, x_mat_skel] = find(matrui_nova_2_skel);
%On l'angle del punt central serà:
x_mat_centr = punt_centr_skel(1); y_mat_centr = punt_centr_skel(2);
angle_pix = abs(atand((y_mat_centr - y_mat_skel)/(x_mat_centr - x_mat_skel)));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean)
angle_pix_mean = angle_pix;
angle_pix_mean(end+1) = angle_pix;
imshow(matrui_nova_2_show_skel, 'InitialMagnification','fit')
line([x_mat_centr, x_mat_skel], [y_mat_centr, y_mat_skel])
title(strcat(string(round(angle_pix, 1)), "degree"))
Veiem en la variable angle_pix_mean els diferents angles, al llarg de cada pixel:
angle_pix_mean
45.0000 26.5651 18.4349 14.0362 11.3099 0 0 7.1250 6.3402 5.7106
BW_skel_regio = BW_skel(matsort_skel(1):matsort_skel(2), matsort_skel(3):matsort_skel(4));
imshow(BW_skel_regio, 'InitialMagnification','fit')
[y_fins_regio, x_finds_regio] = find(BW_skel_regio)
10
10
10
11
11
10
10
10
10
10
imshow(BW_skel_regio, 'InitialMagnification','fit')
for n_cada_angl = 1:length(angle_pix_mean)
cada_angl = angle_pix_mean(end - n_cada_angl +1);
line([x_mat_centr, x_finds_regio(n_cada_angl)], [y_mat_centr, y_fins_regio(n_cada_angl)]);
text(x_finds_regio(n_cada_angl), y_fins_regio(n_cada_angl), string(round(cada_angl, 1)));
Veiem que fixar-nos amb un sol punt no és llògic, o si més no, fixar cada angle amb el punt final.
El que seria més llogic seria veure en quin punt de la imatge perimetral la suma de la diferència entre els angles és més propera a zero.
exemple 2:
I cóm es fa això?
Bé...
Anem-ho a veure.
El que hem de fer és, per a cada píxel de la regió de la imatge primetral, obtenir l'angle que hi ha per a cada píxel de la regió de la imatge esqueletonitzada.
Llavors,
primer de tot, tenim la imatge perimetral, d'un endpoint en concret:
[matriu_nova_perimetral, matrui_nova_2_perimetral, matrui_nova_2_show_perimetral, matsort_perimetral, punt_centr_perimetral] = matriu_nova(BW_perimeter, round(double(valors_endopints(2)))+1, x_endpoint(2), y_endpoint(2));
imshow(matriu_nova_perimetral, 'InitialMagnification','fit')
El mateix, amb la imatge esqueletonitzada
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, round(double(valors_endopints(2)))+1, x_endpoint(2), y_endpoint(2));
imshow(matriu_nova_skel, 'InitialMagnification','fit')
Molt bé, ara hem d'agafar cada píxel, de la imatge perimetral. Agafem en coordenades x i y, per a poder fer l'angle millor (en comptes de index):
[x_perim, y_perim] = find(matriu_nova_perimetral);
El nombre de píxels de la imatge ha de correspondre a la llargada obtinguda del find()
sum(matriu_nova_perimetral(:))
Fem el mateix amb els pixels de la imatge esqueletonitzada.
[x_skel, y_skel] = find(matriu_nova_skel);
En aquest cas la llargada és de 8.
Bé.
Els pixels es juntaràn en funció a aquell que els angles finals de la cua siguin menors.
Això vol dir que em de guardar d'alguna manera els angles, i veure'n l'error, per mitjà de la desviació típica, per exemple.
Ara farem la proba per 1 pixel de la imatge perimetral, i després ho exportarem a cada pixel.
% On guardarem els angles:
angle_pix_mean_proba = [];
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(1))/(x_skel(n_pixel_skel) - x_perim(1))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
angle_pix_mean_proba(end+1) = angle_pix;
line([y_perim(1), y_skel(n_pixel_skel)], [x_perim(1), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
Bieen!
Ara anem a veure l'error que hi ha entre els angles.
angle_pix_mean_proba
0 8.1301 14.0362 20.5560 26.5651 32.0054 36.8699 45.0000
mean(angle_pix_mean_proba)
std(angle_pix_mean_proba)
Veiem que hi ha molta variació.
Ara anem a fer el mateix per a cada angle
% Llista on guardem els angles (opcional)
% Guardem la desviació estándard, per a veure quina és la menor.
for n_pixel_perim = 1:length(y_perim)
% On guardarem els angles:
angle_pix_mean_proba = [];
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(n_pixel_perim))/(x_skel(n_pixel_skel) - x_perim(n_pixel_perim))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
angle_pix_mean_proba(end+1) = angle_pix;
line([y_perim(n_pixel_perim), y_skel(n_pixel_skel)], [x_perim(n_pixel_perim), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
angles_llista_cell{end+1} = angle_pix_mean_proba;
mean(angle_pix_mean_proba)
std(angle_pix_mean_proba)
% Si la desviació estándard és menor:
if std(angle_pix_mean_proba) < std_lower;
std_lower = std(angle_pix_mean_proba);
% Guardem la posicio (per graficar a posteriori)
punt_minor = n_pixel_perim;
% Guardem el punt on l'angle té una sd menor
punt_final_menorangl = [x_perim(n_pixel_perim), y_perim(n_pixel_perim)];
end
ans = 22.8953
ans = 15.1494
ans = 18.6274
ans = 13.8312
ans = 15.9869
ans = 11.4309
ans = 14.7164
ans = 9.7520
ans = 16.4921
ans = 9.5914
ans = 14.8081
ans = 10.0174
ans = 18.1441
ans = 11.9098
ans = 18.4168
ans = 13.4724
ans = 21.5527
ans = 14.7912
ans = 21.4109
ans = 15.9235
ans = 26.6949
ans = 16.1560
ans = 25.8694
ans = 17.3931
ans = 33.1800
ans = 14.4256
ans = 35.9078
ans = 16.6155
ans = 43.3944
ans = 13.2709
ans = 41.9001
ans = 14.1346
ans = 53.9605
ans = 11.2724
ans = 47.0461
ans = 11.9402
ans = 58.1286
ans = 9.3119
ans = 56.4765
ans = 9.6360
ans = 67.1835
ans = 7.1130
ans = 65.4976
ans = 7.1767
ans = 75.2849
ans = 5.0940
ans = 81.3570
ans = 4.2245
ans = 68.0434
ans = 6.0252
ans = 87.9232
ans = 3.1084
ans = 86.3583
ans = 3.0973
ans = 80.7179
ans = 3.5959
ans = 75.2746
ans = 4.3613
ans = 70.1206
ans = 5.1572
Grafiquem aquesta
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(punt_minor))/(x_skel(n_pixel_skel) - x_perim(punt_minor))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
angle_pix_mean_proba(end+1) = angle_pix;
line([y_perim(punt_minor), y_skel(n_pixel_skel)], [x_perim(punt_minor), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
std(angle_pix_mean_proba)
Finalment, tenim el punt on l'angle és menor.
Podem ara graficar aquest amb el endpoint, de manera que obtinguem una línia, la qual juntarem amb la imatge inicial.
matriu_punts_fin = false(size(matriu_nova_perimetral));
matriu_punts_fin(punt_final_menorangl(1), punt_final_menorangl(2)) = true;
matriu_punts_fin(punt_centr_perimetral(1), punt_centr_perimetral(2)) = true;
imshow(matriu_punts_fin, 'InitialMagnification','fit')
% Ara, dels dos punts fem una linia
matriu_punts_linia = bwconvhull(matriu_punts_fin);
imshow(matriu_punts_linia, 'InitialMagnification','fit')
% Si volguéssim, ho podem graficar a la principal
matriu_nova_graficar_fin = matriu_nova_graficar;
matriu_nova_graficar_fin = matriu_nova_graficar_fin|matriu_punts_linia;
imshow(matriu_nova_graficar_fin, 'InitialMagnification','fit')
imshow(imoverlay(matriu_nova_graficar_fin, matriu_punts_linia, "r"), 'InitialMagnification','fit')
Bueeno,
ara ho hem de passar a la imatge principal,
i després farem el mateix, per a cada endpoint. :)
Ho escalem a la imatge original:
Tenim els punts, els cuals guardarem com posicions, i no com imatge, per tal d'optimitzar la imatge. Lo complicat serà veure com passem de la matriu (imatge) petita, a la gran.
imshow(matriu_punts_linia, 'InitialMagnification','fit')
[y_linia, x_linia] = find(matriu_punts_linia)
Quan habiem obtingut la imatge, habiem guardat les coordenades de la mateixa en la seva obtenció:
Això significava que si feiem un BW(x1:x2, y1:y2) amb aquestes regións, obteniem la imatge.
Suposem que són x1, x2, y1, y2:
Si suméssim a les línies:
BW_perimeter_proba = BW_perimeter;
imshow(BW_perimeter_proba)
% Definim els punts x i y
x_linia_escalatBW = x_linia + matsort_perimetral(3)-1;
y_linia_escalatBW = y_linia + matsort_perimetral(1)-1;
BW_perimeter_proba(y_linia_escalatBW, x_linia_escalatBW) = true;
imshow(BW_perimeter_proba)
BW_perimeter_proba_2 = false(size(BW_perimeter_proba));
BW_perimeter_proba_2(y_linia_escalatBW, x_linia_escalatBW) = true;
imshow(imoverlay(BW_skel|BW_perimeter, BW_perimeter_proba_2, "r"))
Ara haurem d'aplicar això en una forma compilada, de manera que esdevingui una sola funció.
Donada una imatge binària, i la seva esqueletonització, el que s'hauria d'obtenir és l'esqueletonització allargada d'aquesta, simplement, per a cada un dels seus endpoints.
% BW_inicial : Imatge binaria inicial
% BW_skel : Imatge esqueletonitzada inicial
% BW_skel_final_estes : imatge esqueletonitzada final
% ÇÇÇ fer que nomes es detecti un objecte. El mes gran si n'hi ha mes d'un.
%imshow(imoverlay(BW_inicial, BW_skel, "r"), 'InitialMagnification','fit')
% _Obtenció dels endpoints_
[x_endpoint, y_endpoint] = find(bwmorph(BW_skel, 'endpoints'));
inx_endpoints = find(bwmorph(BW_skel,'endpoints'));
% Valors de distancia en els endpoints
BW_single_dist = bwdist(~BW_inicial);
%imshow(BW_single_dist, [])
valors_endopints = BW_single_dist(inx_endpoints)
% % Grafiquem els endpoints
% imshow(imoverlay(BW_prob_cropped, BW_skel, "r" ))
% plot(row_find, row_find, 'b.','markersize',14)
% _Obtenció imatge perimetral_
% Busquem punts perimetrals
[boundaries, Leing] = bwboundaries(BW_inicial); % Elapsed time is 0.010365 seconds.
superf_points = boundaries{1};
ind = sub2ind(size(BW_inicial),superf_points(:, 1), superf_points(:, 2))
29630
30036
30035
30441
30440
30846
30845
31251
31657
32063
BW_perimeter = false(size(BW_inicial))
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BW_perimeter(ind) = true;
% La imatge binaria esqueltonitzada final:
BW_skel_final_estes = BW_skel;
for n_endpoint = 1:length(x_endpoint)
% Si el endpoint està tocant al perímetre
if BW_perimeter(x_endpoint(n_endpoint), y_endpoint(n_endpoint))
%imshow(BW_perimeter); hold on
%plot(y_endpoint(1), x_endpoint(1), 'b.','markersize',14); hold off
%BW_perimeter(x_endpoint(1), y_endpoint(1))
%imshow(BW_skel); hold on
%plot(y_endpoint(1), x_endpoint(1), 'b.','markersize',14); hold off
%BW_skel(x_endpoint(1), y_endpoint(1))
%imshow(imoverlay(BW_perimeter, BW_skel, "r"))
% _Obtenció de les matrius_
[matriu_nova_perimetral, matrui_nova_2_perimetral, matrui_nova_2_show_perimetral, matsort_perimetral, punt_centr_perimetral] = matriu_nova(BW_perimeter, round(double(valors_endopints(n_endpoint)))+1, x_endpoint(n_endpoint), y_endpoint(n_endpoint));
imshow(matriu_nova_perimetral, 'InitialMagnification','fit')
%El mateix, amb la imatge esqueletonitzada
[matriu_nova_skel, matrui_nova_2_skel, matrui_nova_2_show_skel, matsort_skel, punt_centr_skel] = matriu_nova(BW_skel, round(double(valors_endopints(n_endpoint)))+1, x_endpoint(n_endpoint), y_endpoint(n_endpoint));
imshow(matriu_nova_skel, 'InitialMagnification','fit')
imshow(imoverlay(matriu_nova_perimetral, matriu_nova_skel, "r"))
% Possible filtre: bwconncomp(matriu_nova_perimetral|matriu_nova_perimetral, 4)
% __Tractament amb matrius__
[x_perim, y_perim] = find(matriu_nova_perimetral);
% Fem el mateix amb els pixels de la imatge esqueletonitzada.
[x_skel, y_skel] = find(matriu_nova_skel);
% Llista on guardem els angles (opcional)
% Guardem la desviació estándard, per a veure quina és la menor.
for n_pixel_perim = 1:length(y_perim)
% On guardarem els angles:
angle_pix_mean_proba = [];
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
imshow(matriu_nova_graficar, 'InitialMagnification','fit')
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(n_pixel_perim))/(x_skel(n_pixel_skel) - x_perim(n_pixel_perim))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba)
angle_pix_mean_proba = angle_pix;
angle_pix_mean_proba(end+1) = angle_pix;
%line([y_perim(n_pixel_perim), y_skel(n_pixel_skel)], [x_perim(n_pixel_perim), x_skel(n_pixel_skel)]);
%text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
angles_llista_cell{end+1} = angle_pix_mean_proba; % ÇÇÇ potser no cal
%mean(angle_pix_mean_proba)
%std(angle_pix_mean_proba)
% Si la desviació estándard és menor:
if std(angle_pix_mean_proba) < std_lower;
std_lower = std(angle_pix_mean_proba);
% Guardem la posicio (per graficar a posteriori)
punt_minor = n_pixel_perim;
% Guardem el punt on l'angle té una sd menor
punt_final_menorangl = [x_perim(n_pixel_perim), y_perim(n_pixel_perim)];
% __Graficació de la regió__
matriu_nova_graficar = matriu_nova_skel|matriu_nova_perimetral;
figure; imshow(matriu_nova_graficar, 'InitialMagnification','fit'); hold on
% Mirem per a cada pixel de la esqueletonització:
for n_pixel_skel = 1:length(x_skel)
angle_pix = abs(atand((y_skel(n_pixel_skel) - y_perim(punt_minor))/(x_skel(n_pixel_skel) - x_perim(punt_minor))));
% Afegim a la mitjana del angle:
if isempty(angle_pix_mean_proba); angle_pix_mean_proba = angle_pix;
else; angle_pix_mean_proba(end+1) = angle_pix; end
line([y_perim(punt_minor), y_skel(n_pixel_skel)], [x_perim(punt_minor), x_skel(n_pixel_skel)]);
text(y_skel(n_pixel_skel), x_skel(n_pixel_skel), string(round(angle_pix, 1)));
matriu_punts_fin = false(size(matriu_nova_perimetral));
matriu_punts_fin(punt_final_menorangl(1), punt_final_menorangl(2)) = true;
matriu_punts_fin(punt_centr_perimetral(1), punt_centr_perimetral(2)) = true;
figure; imshow(matriu_punts_fin, 'InitialMagnification','fit')
% Ara, dels dos punts fem una linia
matriu_punts_linia = bwconvhull(matriu_punts_fin);
figure; imshow(matriu_punts_linia, 'InitialMagnification','fit')
% Si volguéssim, ho podem graficar a la principal
matriu_nova_graficar_fin = matriu_nova_graficar;
matriu_nova_graficar_fin = matriu_nova_graficar_fin|matriu_punts_linia;
figure; imshow(matriu_nova_graficar_fin, 'InitialMagnification','fit')
figure; imshow(imoverlay(matriu_nova_graficar_fin, matriu_punts_linia, "r"), 'InitialMagnification','fit')
%ara ho hem de passar a la imatge principal,
% Ho escalem a la imatge original:
% Tenim els punts, els cuals guardarem com posicions, i no com imatge, per tal d'optimitzar la imatge. Lo complicat serà veure com passem de la matriu (imatge) petita, a la gran.
figure; imshow(matriu_punts_linia, 'InitialMagnification','fit')
[y_linia, x_linia] = find(matriu_punts_linia)
% Quan habiem obtingut la imatge, habiem guardat les coordenades de la mateixa en la seva obtenció:
% Això significava que si feiem un BW(x1:x2, y1:y2) amb aquestes regións, obteniem la imatge.
% Suposem que són x1, x2, y1, y2:
% Si suméssim a les línies:
BW_perimeter_proba = BW_perimeter;
figure; imshow(BW_perimeter_proba)
% Definim els punts x i y
x_linia_escalatBW = x_linia + matsort_perimetral(3)-1;
y_linia_escalatBW = y_linia + matsort_perimetral(1)-1;
% Grafiquem BW_skel amb la regió, obtenint BW_skel_final_estes.
ind_linia_escalatBW = sub2ind(size(BW_skel_final_estes), y_linia_escalatBW, x_linia_escalatBW);
BW_skel_final_estes(ind_linia_escalatBW) = true;
figure; imshow(BW_skel_final_estes)
figure; imshow(imoverlay(BW_skel|BW_perimeter, (BW_skel_final_estes - BW_skel)>0, "r"))
figure; imshow(imoverlay(BW_inicial, BW_skel_final_estes, "r"))
Ús de la funció
[BW_skel_final_estes] = extendre_skel_estes(BW_inicial, BW_skel);
imshow(imoverlay(BW_inicial, BW_skel_final_estes, "r"))
Ha funcionat!
Ara probarem al llarg de varies imatges
for cada_llist_img = 1:length(llistat_imatges)
BW_inicial = llistat_imatges{cada_llist_img};
[~, BW_inicial] = retallar_BWRGBimatge_BB(imageArray, BW_inicial, 5);
BW_skel = bwskel(BW_inicial);
[BW_skel_final_estes] = extendre_skel_estes(BW_inicial, BW_skel);
figure; imshowpair(imoverlay(BW_inicial, BW_skel_final_estes, "r"), imoverlay(BW_inicial, BW_skel, "r"), "montage")
Comparació extendre sense, antic i actual
for cada_llist_img = 1:length(llistat_imatges)
BW_inicial = llistat_imatges{cada_llist_img};
[imageArray_cropped, BW_inicial] = retallar_BWRGBimatge_BB(imageArray, BW_inicial, 5);
BW_skel = bwskel(BW_inicial);
% Extenem, o no, esquelet
% Extenent el esquelet i reduint la única línea
[~, sfMaskBurn_new, dades_imatge_sk1] = esqueletonitzacio_josep(BW_inicial, imageArray_cropped, 1, true, true);
figure; imshow(sfMaskBurn_new); dades_imatge_sk1
% sense extendre esquelet sense reduïr linia
[BW_skel, sfMaskBurn_new, dades_imatge_sk2] = esqueletonitzacio_josep(BW_inicial, imageArray_cropped, 1, false, false);
figure; imshow(sfMaskBurn_new); dades_imatge_sk2
disp(strcat("Variació del ", string(((dades_imatge_sk1 -dades_imatge_sk2)/dades_imatge_sk1)*100), "%"))
end
dades_imatge_sk1 = 707.5189
dades_imatge_sk2 = 697.6905
dades_imatge_sk1 = 662.8255
dades_imatge_sk2 = 653.7544
dades_imatge_sk1 = 185
dades_imatge_sk2 = 153